/*
 * @Date         : 2024-05-21 22:26:00 星期2
 * @Author       : xut
 * @Description  :
 */
import { Controller, Get, Inject, OnModuleInit, Param } from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import { Observable, ReplaySubject, toArray } from 'rxjs';
import { Hero } from './interface/hero/Hero';
import { HeroById } from './interface/hero/HeroById';
import { HERO_PACKAGE } from './hero.constant';
import { Metadata } from '@grpc/grpc-js';

interface HeroService {
  findOne(data: HeroById): Observable<Hero>;
  findOne(data: HeroById, metadata: Metadata): Observable<Hero>;
  findMany(upstream: Observable<HeroById>): Observable<Hero>;
  findMany(
    upstream: Observable<HeroById>,
    metadata: Metadata,
  ): Observable<Hero>;
}

@Controller('hero')
export class HeroClientController implements OnModuleInit {
  private heroService: HeroService;

  // grpc 客户端注册方式之一，首先方式，结合在 hero.module.ts 文件中 ClientModule.register() 注入
  constructor(@Inject(HERO_PACKAGE) private readonly client: ClientGrpc) {}

  // grpc 客户端注册方式之二：@Client
  // @Client({
  //   transport: Transport.GRPC,
  //   options: {
  //     package: 'hero',
  //     protoPath: join(__dirname, 'hero/hero.proto'),
  //   },
  // })
  // client: ClientGrpc;

  onModuleInit() {
    this.heroService = this.client.getService<HeroService>('HeroService');
  }

  @Get()
  getMany(): Observable<Hero[]> {
    const clientMetadata = new Metadata();
    clientMetadata.set('bidi-client-metadata', 'bidi-client-metadata');

    const ids$ = new ReplaySubject<HeroById>();
    ids$.next({ id: 1 });
    ids$.next({ id: 2 });
    ids$.complete();

    const stream = this.heroService.findMany(
      ids$.asObservable(),
      clientMetadata,
    );
    return stream.pipe(toArray());
  }

  @Get(':id')
  getById(@Param('id') id: string): Observable<Hero> {
    const clientMetadata = new Metadata();
    clientMetadata.set('unary-client-metadata', 'unary-client-metadata');

    return this.heroService.findOne({ id: +id }, clientMetadata);
  }
}
